package com.kepler.social.common.utils;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.MissingNode;
import com.kepler.social.common.exception.GenericBusinessException;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.util.List;

public final class  Jackson2Helper {
	private static final ObjectMapper mapper = new ObjectMapper();
	static {
		// 设置输入时忽略在JSON字符串中存在但Java对象实际没有的属性
		mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
	}


	public static String toJsonString(Object obj) {
		if (null == obj) {
			return null;
		}
		try {
			return mapper.writeValueAsString(obj);
		} catch (Exception e) {
			throw new GenericBusinessException(e);
		}
	}

	public static <T> T parsingObject(String jsonString, Class<T> cls) throws GenericBusinessException {
		if (StringUtils.isBlank(jsonString) || null == cls) {
			return null;
		}

		try {
			return mapper.readValue(jsonString, cls);
		} catch (IOException e) {
			throw new GenericBusinessException(e);
		}
	}
	
	public static JsonNode parsingObject(String jsonString) throws GenericBusinessException {
		if (StringUtils.isBlank(jsonString)) {
			return MissingNode.getInstance();
		}
		try {
			return mapper.readTree(jsonString);
		} catch (IOException e) {
			throw new GenericBusinessException(e);
		}
	}

	/**
	 * 支持泛型
	 * 
	 * @param jsonString
	 * @param valueTypeRef
	 * @return T
	 * @Author 杨健/YangJian
	 * @Date 2015年3月30日 下午12:35:45
	 * @Version 1.0.0
	 */
	public static <T> T parsonObject(String jsonString, TypeReference<T> valueTypeRef) {
		if (StringUtils.isBlank(jsonString)) {
			return null;
		}
		try {

			return mapper.readValue(jsonString, valueTypeRef);
		} catch (Exception e) {
			throw new GenericBusinessException(e);
		}
	}

	public static JsonNode readJson(String json){
        try {
            return mapper.readTree(json);
        } catch (Exception e) {
			throw new GenericBusinessException(e);
        }
    }

    public static <T> List<T> jsonToList(String json, Class<T> bean){
        JavaType javaType = mapper.getTypeFactory().constructParametricType(List.class, bean);
        try {
            return mapper.readValue(json, javaType);
        } catch (IOException e) {
			throw new GenericBusinessException(e);
        }
    }

    public static <T> List<T> jsonToListDefaultList(String json, Class<T> bean){
        JavaType javaType = mapper.getTypeFactory().constructParametricType(List.class, bean);
        try {
            return mapper.readValue(json, javaType);
        } catch (IOException e) {
			throw new GenericBusinessException(e);
        }
    }
}
